home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / telecomm / sticpsrc.lzh / SOURCE.ARC / NR7.C < prev    next >
C/C++ Source or Header  |  1990-10-06  |  29KB  |  1,223 lines

  1. /* NET/ROM level 7 processing (user command interpreter) */
  2.  
  3. #include <stdio.h>
  4. #include <ctype.h>
  5. #include "global.h"
  6. #include "mbuf.h"
  7. #include "iface.h"
  8. #include "timer.h"
  9. #include "ax25.h"
  10. #include "lapb.h"
  11. #include "netrom.h"
  12. #include "cmdparse.h"
  13. #include "netuser.h"
  14.  
  15. static struct mbuf *nr7id();
  16. static struct nr_user *find_nr_axuser();
  17. static void del_nr_user(),nr7_send(),nr7_execute();
  18. static void nr7_rxn(),nr7_stnr(),nr7_crx(),nr7_ctx(),nr7_rxa(),nr7_state();
  19.  
  20. static struct nr_user *nr_users;    /* users connected to the NET/ROM */
  21. static struct nr_user *nr_curusr;    /* requesting user */
  22.  
  23. extern struct mbuf *recv_ax25();
  24. extern char hostname[],version[];
  25.  
  26. static char nrlog[] = "%s %s - %s";
  27. static char nrconlog[] = "Connected NET/ROM";
  28. static char nrdwnlog[] = "NET/ROM downlink %s";
  29. static char nrcirlog[] = "NET/ROM circuit ok";
  30. static char nrciflog[] = "NET/ROM circuit ab";
  31. static char nrconnect[] = "Connected to %s\r";
  32. static char nrfailure[] = "Failure with %s\r";
  33. static char nrbusy[] = "Busy from %s\r";
  34. static char nrifunknown[] = "Interface unknown\r";
  35. static char nrnodebusy[] = "Node busy\r";
  36. static char nrinvalid[] = "Invalid callsign\r";
  37.  
  38. /* This is the default receive upcall function, used when
  39.  * someone else connects to us and sends a pid=Text packet.
  40.  * This will start a session with the NET/ROM command interpreter.
  41.  */
  42. void
  43. ax_incom(axp,cnt)
  44. register struct ax25_cb *axp;
  45. int16 cnt;
  46. {
  47.     register struct nr_user *nru;
  48.  
  49.     /* check if NET/ROM handling is supported here */
  50.     if(axp->interface->nriface == NULLNRIFACE ||    /* not NET/ROM iface */
  51.        !axp->interface->nriface->uplink ||        /* no uplinks here */
  52.        !ismycall(&axp->addr.source)){        /* not proper callsign */
  53. #if 0
  54.         tnc_state(axp,DISCONNECTED,CONNECTED,LAPBCONN);/* try interactive */
  55. #else
  56.         disc_ax25(axp);                /* throw him out */
  57. #endif
  58.         return;
  59.     }
  60.  
  61.     /* register new NET/ROM user */
  62.     if((nru = find_nr_axuser(axp,NRU_UP)) != NULLNRUSER ||
  63.        (nru = (struct nr_user *) calloc(1,sizeof(struct nr_user))) == NULLNRUSER) {
  64.         disc_ax25(axp);
  65.         return;
  66.     }
  67.  
  68.     if((nru->next = nr_users) != NULLNRUSER)
  69.         nru->next->prev = nru;
  70.  
  71.     nr_users = nru;
  72.  
  73.     nru->ax25_cb[NRU_UP] = axp;
  74.     nru->iface = axp->interface;
  75.  
  76.     axp->paclen = 256;        /* NET/ROM always has paclen=256 */
  77.     axp->window = 1;        /* use tight flow control */
  78.     axp->r_upcall = nr7_rxa;
  79.     axp->s_upcall = nr7_state;
  80.  
  81.     log_ax(axp,nrconlog);
  82.  
  83.     nr7_rxa(axp,cnt);        /* pass first packet to interpreter */
  84. }
  85.  
  86. /* receive upcall handler for AX.25 Text packets incoming on interface call */
  87.  
  88. static void
  89. nr7_rxa(axp,cnt)
  90. struct ax25_cb *axp;
  91. int16 cnt;
  92. {
  93.     register struct nr_user *nru;
  94.     struct mbuf *bp;
  95.     char inbuf[80];
  96.     struct mbuf *recvl_ax25();
  97.  
  98.     if ((nru = find_nr_axuser(axp,NRU_UP)) == NULLNRUSER) {
  99.         disc_ax25(axp);        /* who are you? */
  100.         return;
  101.     }
  102.  
  103.     while((bp = recvl_ax25(axp,0)) != NULLBUF){ /* get a line of text */
  104.         inbuf[pullup(&bp,inbuf,sizeof(inbuf) - 1)] = '\0';
  105.         free_p(bp);
  106.         nr7_execute(nru,inbuf);    /* execute the command */
  107.     }
  108. }
  109.  
  110. /* state-change upcall handler to be used once Text packets for the NET/ROM
  111.  * command interpreter have been received.
  112.  * it is also used as a DM-sender for the AX.25 port for downlinks
  113.  */
  114.  
  115. static void
  116. nr7_state(axp,old,new,msg)
  117. struct ax25_cb *axp;
  118. int old,new,msg;
  119. {
  120.     register struct nr_user *nru;
  121.  
  122.     switch (new)
  123.     {
  124.     case CONNECTED:
  125.         if (msg == LAPBCONN)    /* can only be the AX.25 port */
  126.         axp->state = DISCONNECTED; /* refuse incoming connections */
  127.                     /* also do processing for DISCONNECTED */
  128.     case DISCONNECTED:
  129.         if ((nru = find_nr_axuser(axp,NRU_UP)) == NULLNRUSER)
  130.         break;
  131.  
  132.         del_nr_user(nru);
  133.         break;
  134.     }
  135. }
  136.  
  137. #ifdef NETROM4
  138. /* receive upcall hand;
  139.     c for NET/ROM Info */
  140.  
  141. void
  142. nr7_rxnr(circ,pkcnt)
  143. register struct nr_circ *circ;
  144. int16 pkcnt;
  145. {
  146.     register struct nr_user *nru;
  147.     char tmp1[10],tmp2[10];
  148.  
  149.     /* register a new user */
  150.  
  151.     if ((nru = (struct nr_user *) circ->user) != NULLNRUSER ||
  152.         (nru = (struct nr_user *) calloc(1,sizeof(struct nr_user))) == NULLNRUSER) {
  153.         nr4_close(circ);
  154.         return;
  155.     }
  156.  
  157.     if ((nru->next = nr_users) != NULLNRUSER)
  158.         nru->next->prev = nru;
  159.  
  160.     nr_users = nru;
  161.  
  162.     nru->nrcirc[NRU_UP] = circ;
  163.     nru->iface = nr_lap;
  164.  
  165.     circ->r_upcall = nr7_rxn;
  166.     circ->s_upcall = nr7_stnr;
  167.     circ->user = (char *) nru;
  168.  
  169.     pax25(tmp1,&circ->dnode);
  170.     pax25(tmp2,&circ->suser);
  171.     log_msg(nrlog,tmp1,tmp2,nrconlog);
  172.  
  173.     nr7_rxn(circ,pkcnt);        /* first packet to interpreter */
  174. }
  175.  
  176. /* receive upcall handler for NET/ROM info after first packet received */
  177.  
  178. static void
  179. nr7_rxn (circ,pkcnt)
  180. register struct nr_circ *circ;
  181. int16 pkcnt;
  182. {
  183.     register struct nr_user *nru;
  184.     struct mbuf *bp;
  185.     char inbuf[80];
  186.     struct mbuf *pullline();
  187.  
  188.     if ((nru = (struct nr_user *) circ->user) == NULLNRUSER) {
  189.         nr4_close(circ);
  190.         return;
  191.     }
  192.  
  193.     circ->rxq = nr4_recv(circ,pkcnt); /* receive all packets and append */
  194.  
  195.     while((bp = pullline(&circ->rxq,0)) != NULLBUF){ /* get a line of text */
  196.         inbuf[pullup(&bp,inbuf,sizeof(inbuf) - 1)] = '\0';
  197.         free_p(bp);
  198.         nr7_execute(nru,inbuf);    /* execute the command */
  199.     }
  200. }
  201.  
  202. /* NET/ROM state-change upcall hand;er to be used once packets received over
  203.    the NET/ROM level 4 circuit */
  204.  
  205. static void
  206. nr7_stnr(circ,old,new)
  207. struct nr_circ *circ;
  208. int old,new;
  209. {
  210.     register struct nr_user *nru;
  211.  
  212.     switch (new)
  213.     {
  214.     case NR4STDISC:
  215.         if ((nru = (struct nr_user *) circ->user) == NULLNRUSER)
  216.         break;
  217.  
  218.         del_nr_user(nru);
  219.         break;
  220.     }
  221. }
  222. #endif
  223.  
  224. /* commands available from NET/ROM */
  225. static int nr7_conn(),nr7_info(),nr7_mheard(),nr7_nodes(),nr7_parms(),
  226.     nr7_ports(),nr7_routes(),nr7_users();
  227. static struct cmds netromcmds[] = {
  228. #ifdef NETROM4
  229.     "CONNECT",    nr7_conn,    0, NULLCHAR,  NULLCHAR,
  230. #endif
  231.     "INFO",        nr7_info,    0, NULLCHAR,  NULLCHAR,
  232.     "MHEARD",    nr7_mheard,    0, NULLCHAR,  NULLCHAR,
  233.     "NODES",    nr7_nodes,    0, NULLCHAR,  NULLCHAR,
  234. #ifdef NR7PARMS
  235.     "PARMS",    nr7_parms,    0, NULLCHAR,  NULLCHAR,
  236. #endif
  237.     "PORTS",    nr7_ports,    0, NULLCHAR,  NULLCHAR,
  238.     "ROUTES",    nr7_routes,    0, NULLCHAR,  NULLCHAR,
  239. #ifdef NETROM4
  240.     "USERS",    nr7_users,    0, NULLCHAR,  NULLCHAR,
  241. #endif
  242.     NULLCHAR,    NULLFP,        0, NULLCHAR,  NULLCHAR
  243. };
  244.  
  245. /* execute a NET/ROM command already in a line buffer */
  246. static void
  247. nr7_execute(nru,inbuf)
  248. register struct nr_user *nru;
  249. char inbuf[];
  250. {
  251.     char *p;
  252.     struct mbuf *bp;
  253.     register struct cmds *cm;
  254.  
  255.     /* when a command comes in, terminate any pending downlinks */
  256.     /* first clear the "user" fields to suppress messages */
  257.  
  258.     if (nru->ax25_cb[NRU_DOWN] != NULLAX25) {
  259.         nru->ax25_cb[NRU_DOWN]->user = NULLCHAR;
  260.         disc_ax25(nru->ax25_cb[NRU_DOWN]);
  261.         nru->ax25_cb[NRU_DOWN] = NULLAX25;
  262.     }
  263.  
  264.     if (nru->nrcirc[NRU_DOWN] != NULLNRCIRC) {
  265.         nru->nrcirc[NRU_DOWN]->user = NULLCHAR;
  266.         nr4_close(nru->nrcirc[NRU_DOWN]);
  267.         nru->nrcirc[NRU_DOWN] = NULLNRCIRC;
  268.     }
  269.  
  270.     rip(inbuf);            /* strip CR and LF chars */
  271.     for(p = inbuf; *p != '\0'; p++) /* convert rest to UPPER case */
  272.         *p = toupper(*p);
  273.  
  274.     nr_curusr = nru;        /* set current user */
  275.  
  276.     if (inbuf[0] != '\0' &&        /* don't parse empty lines */
  277.         (index(inbuf,'$') != NULLCHAR || /* don't parse lines with $ */
  278.          cmdparse(netromcmds,inbuf) < 0)) /* parse a NET/ROM cmd */
  279.     {
  280.         bp = nr7id();
  281.         append(&bp,qstring("Invalid command ("));
  282.  
  283.         for (cm = netromcmds; cm->name != NULLCHAR; cm++) {
  284.         append(&bp,qstring(cm->name));
  285.         append(&bp,qstring(((cm+1)->name != NULLCHAR)? " ":")\r"));
  286.         }
  287.  
  288.         nr7_send(bp);        /* send the error message */
  289.  
  290.         if (++(nru->errors) >= 3) { /* too many errors? */
  291.         if (nru->ax25_cb[NRU_UP] != NULLAX25)
  292.             close_ax25(nru->ax25_cb[NRU_UP]);
  293.  
  294.         if (nru->nrcirc[NRU_UP] != NULLNRCIRC)
  295.             nr4_close(nru->nrcirc[NRU_UP]);
  296.         }
  297.     } else {
  298.         nru->errors = 0;        /* reset errorcnt on good command */
  299.     }
  300.  
  301.     nr_curusr = NULLNRUSER;        /* end current user */
  302. }
  303.  
  304. #ifdef NETROM4
  305. /* AX.25 receive upcall hand;
  306.     c */
  307.  
  308. static void
  309. nr7_arx(axp,cnt)
  310. register struct ax25_cb *axp;
  311. int16 cnt;
  312. {
  313.     registe